import Client from "./game/battle/client";
import Effect from "./game/battle/effect";
import Mgr from "./game/battle/mgr";
import MgrSkill from "./game/battle/mgrSkill";
import Frame from "./game/UI/frame";
import UI from "./game/UI/UI";
import HallClient from "./index/hallClient";
import Music_ts from "./persist/music";
import Persist from "./persist/persist";
import Library from "./studySkill/library";

export const WS_Path:string = "ws://175.27.187.8:8082"; //websocket地址  "ws://175.27.187.8:8082"
export const VERSION:string = "2022.09.01";           //版本号

//用户携带技能
export class UserSkill{
    skill1:number = 0;          //技能1
    skill2:number = 1;          //技能2
    skill3:number = 3;          //技能3
    skill4:number = 4;          //技能4
}
//game中用的技能
export class Skill{
    bh:number;
    name:string;
    type:string;
    cost:number;        //解锁所需技能点
    time:number;        //使用剩余次数
    hold:number;        //充能数
    cooling:number;     //冷却
    desc:string;        //技能描述
    is_unlock:boolean = false;  //是否已经解锁
}

//存储数据
class Data{
    num_win:number = 0;
    num_match:number = 0;
    userSkill:UserSkill = new UserSkill();
}

//临时数据
class Temp{
    arrSkill:Json_skill[] = null;           //全部技能
    gameRecord:GameRecord = null;           //当前正在复盘的对局对象
}


//完成游戏对局
export class GameRecord{
    map:number[];       //地图
    players:object[] = [];   //玩家对象
    action:object[];    //全部行动
}

//json技能
export class Json_skill{
    bh:number;
    name:string;
    type:string;
    cost:number;        //解锁所需技能点
    time:number;        //使用剩余次数
    hold:number;        //充能数
    cooling:number;     //冷却
    desc:string;        //技能描述
    is_unlock:boolean = false;  //未解锁
}


const {ccclass, property} = cc._decorator;

@ccclass
class Global extends cc.Component{

    data:Data = new Data();     //需要存储的数据
    temp:Temp = new Temp();     //临时数据

    //常驻
    persist:Persist;            //提示
    music_ts:Music_ts;          //音乐

    is_checkVersion = false;    //版本正确
    is_dropLine = false;        //是否掉线
    //玩家信息
    id:number;              //websocket 唯一标识

    library:Library;
    
    //game场景
    client:Client;              //房间消息处理器
    hallClient:HallClient;      //大厅消息处理器
    websocket:WebSocket;        //通信器
    mgr:Mgr;                    //游戏总控
    UI:UI;                      //UI总控
    frame:Frame;                //弹框总控
    effect:Effect;              //特效总控
    mgrSkill:MgrSkill;          //分担mgr的一部分技能逻辑压力

    //复盘场景
    is_replay:boolean = false;  //当前是否是在复盘
    //全视野模式
    is_omniscience:boolean = false; 

    seat:Number;    //在房间中的座位号

    /**
     * 获取周围一圈的索引  不包含index
     */
    getAround(index:number){
        let arr = new Array<number>();
        //先左右判断，再在里面判断上下
        if(index%20==19){
            this.checkIndex(arr,index-1);
            this.checkIndex(arr,index+20);
            this.checkIndex(arr,index-21);
            this.checkIndex(arr,index+19);
            this.checkIndex(arr,index-20);
        }else if(index%20==0){
            this.checkIndex(arr,index+1);
            this.checkIndex(arr,index+21);
            this.checkIndex(arr,index-19);
            this.checkIndex(arr,index+20);
            this.checkIndex(arr,index-20);
        }else{
            this.checkIndex(arr,index+1);
            this.checkIndex(arr,index+20);
            this.checkIndex(arr,index+21);
            this.checkIndex(arr,index-19);
            this.checkIndex(arr,index-20);
            this.checkIndex(arr,index-1);
            this.checkIndex(arr,index-21);
            this.checkIndex(arr,index+19);
        }
        return arr;
    }

    /**
     * 获取周围两圈的索引 不包含index
     */
    getAround2(index:number){
        let arr = new Array<number>();
        let arr1 = this.getAround(index);
        for(let i=0;i<arr1.length;i++){
            arr.push(arr1[i]);
            let arr2 = this.getAround(arr1[i]);
            for(let j=0;j<arr2.length;j++){
                arr.push(arr2[j]);
            }
        }
        let set = new Set(arr);
        set.delete(index);
        return Array.from(set);
    }

    /**
     * 检查是否超出0-399
     */
    checkIndex(arr:Array<number>,index:number){
        if(index<0||index>399){
            return ;
        }
        arr.push(index);
    }

    /**
     * 加载技能图片
     */
    loadSf(sprite:cc.Sprite, addres:string){
        cc.resources.load(addres,cc.SpriteFrame, (err, spFrame)=>{
            sprite.spriteFrame = spFrame as cc.SpriteFrame;
        });
    }

    /**
     * json对象转成技能对象
     */
    JsontoSkill(bh:number){
        for(let skill of this.temp.arrSkill){
            if(skill.bh==bh){
                return {...skill};
            }
        }
    }

    /**
     * 减冷却等情况还是要参考json
     */
    getJsonSkill(bh:number){
        for(let skill of this.temp.arrSkill){
            if(skill.bh==bh){
                return skill;
            }
        }
    }

    /**
     * WebSocket 发送
     */
    send(obj:Object){
        this.websocket.send(JSON.stringify(obj));
    }

    /**
     * WebSocket 收到消息方法监听
     */
    webSocketInit(){
        //先判断是哪个场景
        this.websocket.onmessage = event =>{
            const data = JSON.parse(event.data);
            //有 other 表示这不是战斗房中的消息
            if(data.other!=null){
                if(data.other == "heartbeat"){
                    this.checkHeartbeat();
                }else if(this.hallClient==null){
                    HallClient.arr_data.push(data);
                }else{
                    this.hallClient.onMessage(data);
                }
            }else{
                if(this.client==null){
                    Client.arr_data.push(data);
                }else{
                    this.client.onMessage(data);
                }
                
            }
        }
    }

    /**
     * 掉线心跳检测
     */
    checkHeartbeat(){
        this.unscheduleAllCallbacks();
        this.scheduleOnce(()=>{
            this.is_dropLine = true;
            this.persist.tip("网络断开，退游戏吧")
            if(cc.director.getScene().name == "game"){
                cc.director.loadScene("index")
            }
        },3);
    }
}

export default new Global();